#include "base/channel.h"
#include "base/eventloop.h"
#include "base/timer.h"
#include "base/timeeverymap.h"
#include "base/log.h"

#include "base/timeevery.h"
namespace net_tools::base{
Timeevery::Timeevery(func func,timeval begin_time,timeval time,int count,net_tools::Eventloop* eventloop,Timeeverymap* timeeverymap,const std::string& name)
  :timer_(new Timer()),
   timerfd_(timer_->Gettimefd()),
   func_(std::move(func)),
   begin_time_(begin_time),
   time_(time),
   next_time_(begin_time),
   count_(count),
   eventloop_(eventloop),
   timeeverymap_(timeeverymap),
   time_job_name_(std::move(name)),
   is_takeplace_other_(false)
{
  if(timeeverymap_->Add_timejob(time_job_name_,this)){
    is_takeplace_other_ = true;
  }
  NT_LOG_TRACE << "Timejobname: " << time_job_name_ << " CREAT" << NT_LOG_ENDL;
  Set_time();
}
Timeevery::~Timeevery(){
  delete timer_;
};
void Timeevery::Time_out(){
  if(count_ > 0){
    func_();
    --count_;
    next_time_.tv_sec = next_time_.tv_sec + time_.tv_sec;
    next_time_.tv_usec = next_time_.tv_usec + time_.tv_usec;
    if(next_time_.tv_usec >= 1000000){
      next_time_.tv_usec -= 1000000;
      ++next_time_.tv_sec;
    }
    Set_time();
  }else if (count_ == -1){
    func_();
    next_time_.tv_sec = next_time_.tv_sec + time_.tv_sec;
    next_time_.tv_usec = next_time_.tv_usec + time_.tv_usec;
    if(next_time_.tv_usec >= 1000000){
      next_time_.tv_usec -= 1000000;
      ++next_time_.tv_sec;
    }
    Set_time();
  }else{
    timeeverymap_->Del_timejob(time_job_name_);
  }
};
void Timeevery::Clean_timeevery(){
  channel_->Del_to_epoll();
  eventloop_->Free_channel_right_now(channel_);
  delete this;
};
void Timeevery::Set_time(){
  timeval now_time,set;
  gettimeofday(&now_time,NULL);
  set.tv_usec = next_time_.tv_usec - now_time.tv_usec;
  set.tv_sec = next_time_.tv_sec - now_time.tv_sec;
  if(set.tv_usec < 0){
    set.tv_usec += 1000000;
    --set.tv_sec;
  }
  if(set.tv_sec < 0){
    set.tv_usec = 0;
    set.tv_sec = 0;
  }
  timer_->Settime(set);
};

} // namespace net_tools::base